# include <stdio.h>
# include <stdlib.h>
# include <string.h>
#define N 10
#define A 0.5





struct id  // Data structure  to from the bucket or hash table
	{ 
	int key;
	char *password;
	}bucket[N]={0,NULL}; // Array of data structure






int divhash(int key)  //Hashing By Division
	{
	return key%7;
	}

int mhash(int key) //Hashing using multiplication
	{
	float k=key;int s=(0.5*k),j=s%N;
	int f=N*j;
	return f;
	}
		

int ldhash(int key,int i) // Hashing using linear probing
	{
	return ((divhash(key)+i)%N);
	}


int lmhash(int key,int i) // Hashing using linear probing
	{
	return ((divhash(key)+i)%N);
	}
int luhash(int key,int i) // Univeral Hashing
	{
	int sel=(random()%5);
	switch(sel)
		{
		case 0:return ((2*key+5)%17)%10 ;break;
		case 1:return ((7*key+15)%23)%10;break;
		case 2:return ((3*key+1)%11)%10 ;break;
		case 3:return ((9*key+7)%29)%10 ;break;
		case 4:return ((1*key+6)%31)%10 ;break;
		}
	}	

int hashinsert(int key,char *passw,int choice)  // To insert using hashing function chosen by the user
	{
	int i=0,j;
	do
		{
		switch(choice)
			{
			case 1:j=ldhash(key,i);break;
			case 2:j=lmhash(key,i);break;
			case 3:j=luhash(key,i);break;
			}
			
		
		if(!bucket[j].key)           // Slot Check for insertion
			{
			bucket[j].key=key;
			bucket[j].password=strcpy(bucket[j].password,passw);	
			return 1;
			}
		else
			i=i+1;              // Probe increment
		}while(i<N);
	printf("Hash table overflow\n");
	return 0;
	}

int match(int key,char *passw,int choice)
	{
	int i=0,j;
	do
		{
		switch(choice)
			{
			case 1:j=ldhash(key,i);break;
			case 2:j=lmhash(key,i);break;
			case 3:j=luhash(key,i);break;
			}
		if((bucket[j].key==key)&&(!(strcmp(bucket[j].password,passw))))  // To check userid and password
			{
			printf("\nCorrect Password\n");
			return 0;
			}	
		else
			i++;							// Probe increment
		}while((!bucket[j].key)|(i<N));
	printf("\nIncorrect password\n");
	return 1;
	}

int convert(char  *userid)
	{
	int key=0,i;
	char *temp;
	temp=userid;
	for(i=1;i<=strlen(temp);i++,temp++)	// Converting the given userid into an unique key
		key+=((int)(*temp))*i;
	return key;
	}

void enter(int choice)
	{
	int check,key;
	char *userid=NULL,*passw=NULL,fname[30];
	printf("Enter file address\n");
	scanf("%s",fname);
	userid=(char*)malloc(11);
	passw=(char*)malloc(11);
	FILE *fp;
	fp=fopen(fname,"r");
	fscanf(fp,"%s",userid);fscanf(fp,"%s",passw);
	while((!feof(fp))&&(check))
		{
		fscanf(fp,"%s",userid);	
		fscanf(fp,"%s",passw);
		key=convert(userid);
		check=hashinsert(key,passw,choice);
		}
	fclose(fp);
	}
	
				

void show()					// To show the contents of the hash table
	{
	int i=0;
	for(;i<N;i++)
		printf("%d  %s \n",bucket[i].key,bucket[i].password);
	return;
	}


int main()
	{
	int key,ans,check,choice,r;
	for(r=0;r<N;r++)
		{
		bucket[r].password=(char*)malloc(11);
		}
	char *userid=NULL;
	char *passw=NULL;
	passw=(char*)malloc(11);
	userid=(char*)malloc(11);
	printf("Enter hashing function of your choice from the given menu\n");
	printf("1: Hashing using division \n");
	printf("2: Hashing using multiplication\n");
	printf("3: Universal hashing\n");
	scanf("%d",&choice);
	enter(choice);
	
	
	int k=0;
	do
		{
		printf("\nEnter userid: ");
		scanf("%s",userid);
		printf("Enter password: ");
		scanf("%s",passw);
		key=convert(userid);
		ans=match(key,passw,choice);
		if(ans)
			k++;
		else
			return;
		}while(k<3);
	printf("\nAccess denied too many tries");	
	return 0;
	}
